﻿using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using WeShare.WeiXin.Common;
using WeShare.WeiXin.Common.EnumKey;
using WeShare.WeiXin.Mp.MaterialLib.Entity;

namespace WeShare.WeiXin.Mp.MaterialLib
{
    public class MaterialApi
    {
        /// <summary>
        /// 上传临时素材
        /// </summary>
        /// <param name="filename">服务器文件的物理路径，可用Request.MapPath将虚拟路径 转换为物理路径。也可为网络路径，如：http://XXXX</param>
        /// <param name="type"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static MediaRes AddTemp(string filename, MaterialType type, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/media/upload?access_token={OpenApi.GetToken(tokenOrAppId)}&type={type.ToString()}";
            var form = new List<FormEntity> { new FormEntity { IsFile = true, Name = "media", Value = filename } };
            return HttpUtil.UploadResult<MediaRes>(url, form);
        }
        /// <summary>
        /// 添加多图文
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="arts"></param>
        /// <param name="istemp">是否是临时素材</param>
        /// <returns></returns>
        public static MediaRes AddNews(Articles arts, bool istemp = false, string tokenOrAppId = "")
        {
            var url = $"https://api.weixin.qq.com/cgi-bin/material/add_news?access_token={OpenApi.GetToken(tokenOrAppId)}";
            if (istemp)
            {
                url = $"https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token={OpenApi.GetToken(tokenOrAppId)}";
            }
            return HttpUtil.PostResult<MediaRes>(arts, url);
        }
        /// <summary>
        /// 上传图文内图片，获取url
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="filename">服务器文件的物理路径，可用Request.MapPath将虚拟路径 转换为物理路径。也可为网络路径，如：http://XXXX</param>
        /// <returns></returns>
        public static NewImgUrlRes UploadNewImgUrl(string filename, string tokenOrAppId = "")
        {
            var url = $"https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={OpenApi.GetToken(tokenOrAppId)}";
            var form = new List<FormEntity> { new FormEntity { IsFile = true, Name = "media", Value = filename } };
            return HttpUtil.UploadResult<NewImgUrlRes>(url, form);
        }
        /// <summary>
        /// 上传永久素材
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="filename">文件名</param>
        /// <param name="type">类型</param>
        /// <param name="videoTitle">视频标题，视频素材时有效</param>
        /// <param name="videoDesc">视频描述，视频素材时有效</param>
        /// <returns></returns>
        public static MediaRes Add(string filename, MaterialType type, string videoTitle = "", string videoDesc = "", string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={OpenApi.GetToken(tokenOrAppId)}&type={type.ToString()}";
            var form = new List<FormEntity> { new FormEntity { IsFile = true, Name = "media", Value = filename } };
            if (!string.IsNullOrEmpty(videoTitle))
            {
                form.Add(new FormEntity { IsFile = false, Name = "description", Value = JsonConvert.SerializeObject(new { title = videoTitle, introduction = videoDesc }) });
            }
            return HttpUtil.UploadResult<MediaRes>(url, form);
        }

        /// <summary>
        /// 获取临时素材url
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="mediaId"></param>
        /// <returns></returns>
        public static string GetTempUrl(string mediaId, string tokenOrAppId = "")
        {
            var url =
            "https://api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}";
            return string.Format(url, OpenApi.GetToken(tokenOrAppId), mediaId);
        }
        /// <summary>
        /// 获取通过jssdk的uploadVoice接口上传的高清语音素材的url
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static string GetJsFileUrl(string mediaId, string tokenOrAppId = "")
        {
            return
                $"https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token={OpenApi.GetToken(tokenOrAppId)}&media_id={mediaId}";
        }
        /// <summary>
        /// 获取临时素材的内容
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="mediaId">素材的id</param>
        /// <param name="ms">文件流。请求成功后，将响应结果填充到此流中</param>
        /// <returns></returns>
        public static BaseRes GetTempFile(string mediaId, FileStreamInfo ms, string tokenOrAppId = "")
        {
            var url = GetTempUrl(mediaId, tokenOrAppId);
            var ret = HttpUtil.HttpGet(url, ms);
            if (ret == "")
            {
                return new BaseRes { errcode = 0 };
            }
            return JsonConvert.DeserializeObject<BaseRes>(ret);
        }


        /// <summary>
        /// 获取临时素材的内容
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="mediaId">素材的id</param>
        /// <param name="ms">文件流。请求成功后，将响应结果填充到此流中</param>
        /// <returns></returns>
        public static BaseRes GetJsFile(string mediaId, FileStreamInfo ms, string tokenOrAppId = "")
        {
            var url = GetJsFileUrl(mediaId, tokenOrAppId);
            var ret = HttpUtil.HttpGet(url, ms);
            if (ret == "")
            {
                return new BaseRes { errcode = 0 };
            }
            return JsonConvert.DeserializeObject<BaseRes>(ret);
        }

        /// <summary>
        /// 获取永久图文素材
        /// </summary>
        /// <param name="mediaId">媒体ID</param>
        /// <param name="tokenOrAppId">全局凭证</param>
        public static ArticleRes GetNews(string mediaId, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={OpenApi.GetToken(tokenOrAppId)}";
            return HttpUtil.PostResult<ArticleRes>(new { media_id = mediaId }, url);
        }
        /// <summary>
        /// 获取视频素材
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static VideoRes GetVideo(string mediaId, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={OpenApi.GetToken(tokenOrAppId)}";
            return HttpUtil.PostResult<VideoRes>(new { media_id = mediaId }, url);
        }
        /// <summary>
        /// 获取除了视频，图文素材之外的其他素材
        /// </summary>
        public static BaseRes Get(string mediaId, FileStreamInfo ms, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={OpenApi.GetToken(tokenOrAppId)}";

            var ret = HttpUtil.HttpPost(url, JsonConvert.SerializeObject(new { media_id = mediaId }), ms);
            if (ret == "")
            {
                return new BaseRes { errcode = 0 };
            }
            return JsonConvert.DeserializeObject<BaseRes>(ret);
        }
        /// <summary>
        /// 删除永久素材
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static BaseRes Del(string mediaId, string tokenOrAppId = "")
        {
            var url = $"https://api.weixin.qq.com/cgi-bin/material/del_material?access_token={OpenApi.GetToken(tokenOrAppId)}";
            return HttpUtil.PostResult<BaseRes>(new { media_id = mediaId }, url);
        }
        /// <summary>
        /// 修改永久图文素材
        /// </summary>
        /// <param name="tokenOrAppId">调用凭据</param>
        /// <param name="mediaId">图文素材ID</param>
        /// <param name="index">要更新的文章在图文消息中的位置（多图文消息时，此字段才有意
        ///   义），第一篇为0</param>
        /// <param name="article">图文实体。此处表示的是修改后的图文信息</param>
        public static BaseRes UpdateNewItem(string mediaId, int
        index, Article article, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/update_news?access_token={OpenApi.GetToken(tokenOrAppId)}";
            var obj = new
            {
                media_id = mediaId,
                index = index,
                articles = article
            };
            return HttpUtil.PostResult<BaseRes>(obj, url);
        }
        /// <summary>
        /// 获取永久素材总数
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static MaterialCount GetCount(string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token={OpenApi.GetToken(tokenOrAppId)}";
            return HttpUtil.GetResult<MaterialCount>(url);
        }
        /// <summary>
        /// 获取永久素材列表，会包含公众号在公众平台官网素材管理模块中新建的图文消息、语音、视
        /// 频等素材（但需要先通过获取素材列表来获知素材的media_id）
        ///临时素材无法通过本接口获取
        /// </summary>
        /// <param name="mediaType">素材类型</param>
        /// <param name="index">从全部素材的指定索引开始返回。
        ///0表示从第一个素材返回</param>
        /// <param name="count">返回素材的数量，取值在1到20之间</param>
        /// <param name="tokenOrAppId">全局票据</param>
        public static Materials GetList(MaterialType mediaType, int index, int
        count, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={OpenApi.GetToken(tokenOrAppId)}";
            var obj = new { type = mediaType.ToString(), offset = index, count = count };
            return HttpUtil.PostResult<Materials>(obj, url);
        }
#if !NET40
        /// <summary>
        /// 获取临时文件的内容
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="ms"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static async Task<BaseRes> GetTempFileAsync(string mediaId, FileStreamInfo ms, string tokenOrAppId = "")
        {
            var url = GetTempUrl(mediaId, tokenOrAppId);
            var ret = await HttpUtil.HttpGetAsync(url, ms);
            if (ret == "")
            {
                return new BaseRes { errcode = 0 };
            }
            return JsonConvert.DeserializeObject<BaseRes>(ret);
        }

        /// <summary>
        /// 上传临时素材
        /// </summary>
        /// <param name="filename">服务器文件的物理路径，可用Request.MapPath将虚拟路径 转换为物理路径。也可为网络路径，如：http://XXXX</param>
        /// <param name="type"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static async Task<MediaRes> AddTempAsync(string filename, MaterialType type, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/media/upload?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}&type={type.ToString()}";
            var form = new List<FormEntity> { new FormEntity { IsFile = true, Name = "media", Value = filename } };
            return await HttpUtil.UploadResultAsync<MediaRes>(url, form);
        }
        /// <summary>
        /// 添加多图文。如果需要在群发图文中插入小程序，则在调用上传图文消息素材接口时，需在content字段中添加小程序跳转链接，有以下三种样式的可供选择。
        /// 小程序卡片跳转小程序，代码示例：
        /// <mp-miniprogram data-miniprogram-appid="wx123123123" data-miniprogram-path="pages/index/index" data-miniprogram-title="小程序示例" data-progarm-imageurl="http://mmbizqbic.cn/demo.jpg"></mp-miniprogram>
        ///文字跳转小程序，代码示例：
        ///<p><a data-miniprogram-appid="wx123123123" data-miniprogram-path="pages/index" href="">点击文字跳转小程序</a></p>
        /// 图片跳转小程序，代码示例：
        /// <p><a data-miniprogram-appid="wx123123123" data-miniprogram-path="pages/index" href=""><img src = "http://mmbiz.qpic.cn/mmbiz_jpg/demo/0?wx_fmt=jpg" alt="" data-width="null" data-ratio="NaN"></a></p>
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="arts"></param>
        /// <param name="istemp">是否是临时素材</param>
        /// <returns></returns>
        public static async Task<MediaRes> AddNewsAsync(Articles arts, bool istemp = false, string tokenOrAppId = "")
        {
            var url = $"https://api.weixin.qq.com/cgi-bin/material/add_news?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            if (istemp)
            {
                url = $"https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            }
            return await HttpUtil.PostResultAsync<MediaRes>(arts, url);
        }
        /// <summary>
        /// 上传图文内图片，获取url
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="filename">服务器文件的物理路径，可用Request.MapPath将虚拟路径 转换为物理路径。也可为网络路径，如：http://XXXX</param>
        /// <returns></returns>
        public static async Task<NewImgUrlRes> UploadNewImgUrlAsync(string filename, string tokenOrAppId = "")
        {
            var url = $"https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            var form = new List<FormEntity> { new FormEntity { IsFile = true, Name = "media", Value = filename } };
            return await HttpUtil.UploadResultAsync<NewImgUrlRes>(url, form);
        }
        /// <summary>
        /// 上传永久素材
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="filename">文件名</param>
        /// <param name="type">类型</param>
        /// <param name="videoTitle">视频标题，视频素材时有效</param>
        /// <param name="videoDesc">视频描述，视频素材时有效</param>
        /// <returns></returns>
        public static async Task<MediaRes> AddAsync(string filename, MaterialType type, string videoTitle = "", string videoDesc = "", string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}&type={type.ToString()}";
            var form = new List<FormEntity> { new FormEntity { IsFile = true, Name = "media", Value = filename } };
            if (!string.IsNullOrEmpty(videoTitle))
            {
                form.Add(new FormEntity { IsFile = false, Name = "description", Value = JsonConvert.SerializeObject(new { title = videoTitle, introduction = videoDesc }) });
            }
            return await HttpUtil.UploadResultAsync<MediaRes>(url, form);
        }

        /// <summary>
        /// 获取临时素材url
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="mediaId"></param>
        /// <returns></returns>
        public static async Task<string> GetTempUrlAsync(string mediaId, string tokenOrAppId = "")
        {
            var url =
            "https://api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}";
            return string.Format(url, await OpenApi.GetTokenAsync(tokenOrAppId), mediaId);
        }
        /// <summary>
        /// 获取通过jssdk的uploadVoice接口上传的高清语音素材的url
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static async Task<string> GetJsFileUrlAsync(string mediaId, string tokenOrAppId = "")
        {
            return
                $"https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}&media_id={mediaId}";
        }

        /// <summary>
        /// 获取临时素材的内容
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <param name="mediaId">素材的id</param>
        /// <param name="ms">文件流。请求成功后，将响应结果填充到此流中</param>
        /// <returns></returns>
        public static async Task<BaseRes> GetJsFileAsync(string mediaId, FileStreamInfo ms, string tokenOrAppId = "")
        {
            var url = await GetJsFileUrlAsync(mediaId, tokenOrAppId);
            var ret = await HttpUtil.HttpGetAsync(url, ms);
            if (ret == "")
            {
                return new BaseRes { errcode = 0 };
            }
            return JsonConvert.DeserializeObject<BaseRes>(ret);
        }

        /// <summary>
        /// 获取永久图文素材
        /// </summary>
        /// <param name="mediaId">媒体ID</param>
        /// <param name="tokenOrAppId">全局凭证</param>
        public static async Task<ArticleRes> GetNewsAsync(string mediaId, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            return await HttpUtil.PostResultAsync<ArticleRes>(new { media_id = mediaId }, url);
        }
        /// <summary>
        /// 获取视频素材
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static async Task<VideoRes> GetVideoAsync(string mediaId, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            return await HttpUtil.PostResultAsync<VideoRes>(new { media_id = mediaId }, url);
        }
        /// <summary>
        /// 获取除了视频，图文素材之外的其他素材
        /// </summary>
        public static async Task<BaseRes> GetAsync(string mediaId, FileStreamInfo ms, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";

            var ret = await HttpUtil.HttpPostAsync(url, JsonConvert.SerializeObject(new { media_id = mediaId }), ms);
            if (ret == "")
            {
                return new BaseRes { errcode = 0 };
            }
            return JsonConvert.DeserializeObject<BaseRes>(ret);
        }
        /// <summary>
        /// 删除永久素材
        /// </summary>
        /// <param name="mediaId"></param>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static async Task<BaseRes> DelAsync(string mediaId, string tokenOrAppId = "")
        {
            var url = $"https://api.weixin.qq.com/cgi-bin/material/del_material?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            return await HttpUtil.PostResultAsync<BaseRes>(new { media_id = mediaId }, url);
        }
        /// <summary>
        /// 修改永久图文素材
        /// </summary>
        /// <param name="tokenOrAppId">调用凭据</param>
        /// <param name="mediaId">图文素材ID</param>
        /// <param name="index">要更新的文章在图文消息中的位置（多图文消息时，此字段才有意
        ///   义），第一篇为0</param>
        /// <param name="article">图文实体。此处表示的是修改后的图文信息</param>
        public static async Task<BaseRes> UpdateNewItemAsync(string mediaId, int
        index, Article article, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/update_news?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            var obj = new
            {
                media_id = mediaId,
                index = index,
                articles = article
            };
            return await HttpUtil.PostResultAsync<BaseRes>(obj, url);
        }
        /// <summary>
        /// 获取永久素材总数
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static async Task<MaterialCount> GetCountAsync(string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            return await HttpUtil.GetResultAsync<MaterialCount>(url);
        }
        /// <summary>
        /// 获取永久素材列表，会包含公众号在公众平台官网素材管理模块中新建的图文消息、语音、视
        /// 频等素材（但需要先通过获取素材列表来获知素材的media_id）
        ///临时素材无法通过本接口获取
        /// </summary>
        /// <param name="mediaType">素材类型</param>
        /// <param name="index">从全部素材的指定索引开始返回。
        ///0表示从第一个素材返回</param>
        /// <param name="count">返回素材的数量，取值在1到20之间</param>
        /// <param name="tokenOrAppId">全局票据</param>
        public static async Task<Materials> GetListAsync(MaterialType mediaType, int index, int
        count, string tokenOrAppId = "")
        {
            var url =
                $"https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={await OpenApi.GetTokenAsync(tokenOrAppId)}";
            var obj = new { type = mediaType.ToString(), offset = index, count = count };
            return await HttpUtil.PostResultAsync<Materials>(obj, url);
        }
#endif

    }
}
